package com.yxzx.api.controller;


import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.yxzx.api.dto.JWTToken;
import com.yxzx.api.dto.RegisterReq;
import com.yxzx.api.dto.RestStatusCode;
import com.yxzx.api.dto.SigInDto;
import com.yxzx.api.entity.User;
import com.yxzx.api.exception.CustomException;
import com.yxzx.api.service.IUserService;
import com.yxzx.api.util.CaptchaUtil;
import com.yxzx.security.jwt.JwtFilter;
import com.yxzx.security.jwt.TokenProvider;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.annotation.Secured;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.security.RolesAllowed;
import java.time.LocalDateTime;
import java.util.List;

/**
 * <p>
 * 用户表 前端控制器
 * </p>
 *
 * @author YWB
 * @since 2020-09-06
 */
@RestController
@RequestMapping("/api/user")
public class UserController {


    @Autowired
    private IUserService userService;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    private AuthenticationManagerBuilder builder;

    @Autowired
    private TokenProvider tokenProvider;

    @Autowired
    private RedisTemplate<String,String> redisTemplate;



    @PostMapping("/signIn")
    @ApiOperation("登录")
    public ResponseEntity<JWTToken> signIn(@RequestBody(required = true) @ApiParam("登录实体对象") SigInDto sigInDto){
        UsernamePasswordAuthenticationToken token=
                new UsernamePasswordAuthenticationToken(sigInDto.getName(),sigInDto.getPassword());

        //认证后返回token对象
        Authentication authenticate = builder.getObject().authenticate(token);

        //将认证对象放到安全框架上下文
        SecurityContextHolder.getContext().setAuthentication(authenticate);

        HttpHeaders headers=new HttpHeaders();
        //生成token
        String backToken=tokenProvider.createToken(authenticate);
        headers.add(JwtFilter.AUTHORIZATION_HEADER,"Bearer "+backToken);



        return new ResponseEntity<>(new JWTToken(backToken),headers, HttpStatus.OK);
    }

    @PostMapping("/signUp")
    @ApiOperation("注册")
    public ResponseEntity<JWTToken> register(@RequestBody(required = true) @ApiParam("用户注册信息") RegisterReq user){


        //验证短信验证码
        String key= CaptchaUtil.SMS_CAPTCHA_KEY+user.getName();

        String smsCode=redisTemplate.boundValueOps(key).get();
        System.out.println("手机短信验证码smsCode："+smsCode);
        if(StringUtils.hasText(smsCode)&&smsCode.equalsIgnoreCase(user.getSmsCode())){
            System.out.println("**************手机验证码验证通过");
        }else {
            throw new CustomException(user.getName(), RestStatusCode.SMS_CHECK_ERROR.getCode(),RestStatusCode.SMS_CHECK_ERROR.getMessage());
        }

        //1.检查是否注册
        User info=new User();
        info.setName(user.getName());

        QueryWrapper<User> query=new QueryWrapper<>(info);
        List<User> list = userService.list(query);

        if(!list.isEmpty()){
            throw new CustomException(user.getName(),RestStatusCode.SIGNUP_ERROR.getCode(),RestStatusCode.SIGNUP_ERROR.getMessage());//用户名，返回状态码，返回信息
        }

        //对密码进行加密
        info.setPassword(passwordEncoder.encode(user.getPassword()));
        info.setPhone(user.getName());
        info.setCreateTime(LocalDateTime.now());
        info.setUpdateTime(LocalDateTime.now());
        info.setDeleted(0);

        userService.save(info);

        SigInDto dto=new SigInDto(user.getName(),user.getPassword());
        //注册完调用登录方法，生成token，返回客户端
        return signIn(dto);

    }


    @GetMapping("/getUserInfo")
    @PreAuthorize("hasAuthority('ROLE_USER')")
//    @PreAuthorize("hasRole('USER')")
//    @Secured("ROLE_USER")
//    @RolesAllowed(("ROLE_USER"))
    public ResponseEntity<User> getUserInfo(){

        //从上下文中取得
        Authentication authentication= SecurityContextHolder.getContext().getAuthentication();

        String userName = authentication.getName();

        //根据用户名查询用户
        QueryWrapper<User> queryWrapper=new QueryWrapper();
        queryWrapper.eq("name",userName);

        User user = userService.getOne(queryWrapper);

        user.setPassword(null);
        return ResponseEntity.ok(user);
    }

}
